
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Spring事务管理 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>Spring事务管理 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">Spring事务管理的四个核心组件是什么？它们各自的作用是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring事务管理的四个核心组件是：1. PlatformTransactionManager：事务管理器接口，定义了开始、提交和回滚等基本操作。2. TransactionDefinition：事务的定义，规定了隔离级别、传播行为等属性。3. TransactionStatus：事务状态对象，记录当前事务的状态信息。4. TransactionInterceptor：事务拦截器，负责在方法调用时管理事务。</div>
          </div>
          <div class="card-source">来源: 1. Spring 事务管理的核心组件</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">模式</div>
          <div class="card-question">Spring支持哪两种事务管理模式？它们的主要区别是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">模式</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring支持声明式事务管理和编程式事务管理。主要区别在于：声明式事务通过注解（如@Transactional）或XML配置，由Spring自动管理事务生命周期；而编程式事务则需要开发人员通过API（如PlatformTransactionManager）显式地在代码中控制事务的开始、提交和回滚。</div>
          </div>
          <div class="card-source">来源: 2. Spring 事务管理的模式</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Spring的声明式事务管理是如何实现的？其中最常用的方式是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Spring的声明式事务管理是通过AOP（面向切面编程）来实现的。Spring AOP会拦截被@Transactional注解标记的方法调用，并在方法执行前后处理事务的开始、提交或回滚等操作。最常见的方式就是使用`@Transactional`注解。</div>
          </div>
          <div class="card-source">来源: 3. 声明式事务管理的实现</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在声明式事务中，`TransactionInterceptor`扮演了什么关键角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`TransactionInterceptor`是声明式事务管理的关键组件。它作为一个方法拦截器，在目标方法执行前后介入，首先获取方法的事务属性，然后使用`PlatformTransactionManager`来启动、提交或回滚事务，从而将事务管理逻辑与业务代码解耦。</div>
          </div>
          <div class="card-source">来源: 3.2. 事务拦截器：TransactionInterceptor</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">`PlatformTransactionManager`接口定义了哪三个核心方法来管理事务？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">该接口定义了三个核心方法：1. `getTransaction(TransactionDefinition definition)`：根据事务定义开始一个新事务并返回事务状态。2. `commit(TransactionStatus status)`：提交给定的事务。3. `rollback(TransactionStatus status)`：回滚给定的事务。</div>
          </div>
          <div class="card-source">来源: 3.3. 事务管理器：PlatformTransactionManager</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">什么是事务传播行为？请说明`REQUIRED`和`REQUIRES_NEW`两种传播行为的区别。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">事务传播行为用于控制当一个事务方法调用另一个事务方法时，事务应该如何传播。`REQUIRED`表示如果当前存在事务，则加入该事务，如果不存在，则创建一个新事务。`REQUIRES_NEW`表示总是创建一个新的事务，如果当前已存在事务，则会将当前事务挂起。</div>
          </div>
          <div class="card-source">来源: 4. 事务传播行为（Propagation）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">什么是事务隔离级别？`DataSourceTransactionManager`是如何设置隔离级别的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">事务隔离级别用于控制事务之间的可见性，防止脏读、不可重复读等问题。在`DataSourceTransactionManager`中，它通过在`getTransaction`方法内调用JDBC连接的`setTransactionIsolation()`方法来设置从`TransactionDefinition`中获取的隔离级别。</div>
          </div>
          <div class="card-source">来源: 5. 事务隔离级别（Isolation）</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">`@Transactional`注解可以配置哪些主要的事务属性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">根据文档中的源码定义，`@Transactional`注解可以配置多个事务属性，主要包括：传播行为（propagation）、隔离级别（isolation）、超时时间（timeout）、是否为只读事务（readOnly）以及指定回滚的异常（rollbackFor）。</div>
          </div>
          <div class="card-source">来源: 3.1. @Transactional 注解的解析</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当事务被设置为只读（readOnly=true）时，`DataSourceTransactionManager`会如何进行优化？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当事务被定义为只读时，`DataSourceTransactionManager`在获取数据库连接后，会调用连接的`setReadOnly(definition.isReadOnly())`方法。这会向数据库驱动提示该事务不会进行写操作，数据库可以据此进行性能优化。</div>
          </div>
          <div class="card-source">来源: 6.2. 只读事务</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
